home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-2.iso / os2 / gnucal.zip / gcal_fil.c < prev    next >
C/C++ Source or Header  |  1995-11-29  |  34KB  |  1,121 lines

  1. /*
  2. *  gcal_fil.c:  Managing and accessing resource, include and response files
  3. *
  4. *
  5. *  Copyright (C) 1994, 1995 Thomas Esken
  6. *
  7. *  This software doesn't claim completeness, correctness or usability.
  8. *  On principle I will not be liable for any damages or losses (implicit
  9. *  or explicit), which result from using or handling my software.
  10. *  If you use this software, you agree without any exception to this
  11. *  agreement, which binds you LEGALLY !!
  12. *
  13. *  This program is free software; you can redistribute it and/or modify
  14. *  it under the terms of the `GNU General Public License' as published by
  15. *  the `Free Software Foundation'; either version 2, or (at your option)
  16. *  any later version.
  17. *
  18. *  You should have received a copy of the `GNU General Public License'
  19. *  along with this program; if not, write to the:
  20. *    Free Software Foundation
  21. *    59 Temple Place, Suite 330
  22. *    Boston, MA 02111-1307  USA
  23. */
  24.  
  25.  
  26.  
  27. #ifdef RCSID
  28. static char rcsid[]="$Id: gcal_fil.c 0.38 1995/11/29 00:03:08 tom Exp $";
  29. #endif
  30.  
  31.  
  32.  
  33. /*
  34. *  Include header files
  35. */
  36. #include "gcal_tai.h"
  37. #if HAVE_ASSERT_H
  38. #  include <assert.h>
  39. #endif
  40. #if HAVE_CTYPE_H
  41. #  include <ctype.h>
  42. #endif
  43. #ifdef GCAL_SHELL
  44. #  if HAVE_UNISTD_H
  45. #    include <unistd.h>
  46. #  endif
  47. #endif
  48. #include "gcal.h"
  49.  
  50.  
  51.  
  52. /*
  53. *  Function prototypes
  54. */
  55. #if __cplusplus
  56. extern "C"
  57. {
  58. #endif
  59. #if USE_RC
  60. /*
  61. ************************************************** Defined in `gcal.c'
  62. */
  63. IMPORT int
  64. eval_longopt __P_((char *longopt,
  65.                    int  *longopt_symbolic));
  66. /*
  67. ************************************************** Defined in `gcal_rc.c'
  68. */
  69. IMPORT Bool
  70. set_dvar __P_((const char      *line_buffer,
  71.                const char      *filename,
  72.                const int        line,
  73.                const Dvar_enum  mode));
  74. #endif
  75. /*
  76. ************************************************** Defined in `gcal_tty.c'
  77. */
  78. IMPORT void
  79. print_text __P_((      FILE       *fp,
  80.                        char       *txt_line,
  81.                  const Dmode_enum  mode));
  82. /*
  83. ************************************************** Defined in `gcal_utl.c'
  84. */
  85. IMPORT VOID_PTR
  86. my_malloc __P_((const int   amount,
  87.                 const int   exit_status,
  88.                 const char *module_name,
  89.                 const int   module_line,
  90.                 const char *var_name,
  91.                 const int   var_contents));
  92. IMPORT VOID_PTR
  93. my_realloc __P_((      VOID_PTR  ptr_memblock,
  94.                  const int       amount,
  95.                  const int       exit_status,
  96.                  const char     *module_name,
  97.                  const int       module_line,
  98.                  const char     *var_name,
  99.                  const int       var_contents));
  100. IMPORT void
  101. my_error __P_((const int   exit_status,
  102.                const char *module_name,
  103.                const int   module_line,
  104.                const char *var_name,
  105.                const int   var_contents));
  106. IMPORT int
  107. days_of_february __P_((const int year));
  108. /*
  109. ************************************************** Defined in `gcal_fil.c'
  110. */
  111. EXPORT FILE *
  112. file_open __P_((      char       *filename,
  113.                 const Fmode_enum  mode));
  114. EXPORT char *
  115. file_read_line __P_((      FILE       *fp,
  116.                            char       *line_buffer,
  117.                            int        *in_pool,
  118.                            char       *pool,
  119.                            char       *ptr_pool,
  120.                      const char       *filename,
  121.                            int        *line,
  122.                      const Fmode_enum  mode,
  123.                            Bool       *is_include,
  124.                            Bool       *is_dvar));
  125. EXPORT void
  126. insert_response_file __P_((      char *filename,
  127.                            const char *opt_list,
  128.                                  int  *my_argc_max,
  129.                                  int  *my_argc,
  130.                                  char *my_argv[]));
  131. EXPORT void
  132. write_log_file __P_((const char       *filename,
  133.                      const Fmode_enum  mode,
  134.                      const char       *mode_msg,
  135.                      const int         argc,
  136.                            char       *argv[]));
  137. LOCAL void
  138. make_absolute_filename __P_((const char *directory,
  139.                              const char *filename));
  140. LOCAL FILE *
  141. get_file_ptr __P_((      FILE       *fp,
  142.                    const char       *filename,
  143.                    const Fmode_enum  mode,
  144.                          Bool       *is_first));
  145. #if __cplusplus
  146. }
  147. #endif
  148.  
  149.  
  150.  
  151. /*
  152. *  Declare public(extern) variables
  153. */
  154. IMPORT const int    dvec[MONTH_MAX];           /* Amount of days in months */
  155. IMPORT Hls_struct   ehls1s;                    /* Effective hls 1 start (current day) */
  156. IMPORT Hls_struct   ehls1e;                    /* Effective hls 1 end (current day) */
  157. IMPORT Hls_struct   ehls2s;                    /* Effective hls 2 start (holiday) */
  158. IMPORT Hls_struct   ehls2e;                    /* Effective hls 2 end (holiday) */
  159. #if HAVE_ASSERT_H
  160. IMPORT Uint         testval;                   /* Set to INT_MAX for checking the maximum table range */
  161. #endif
  162. IMPORT int          warning_level;             /* --debug[=0...WARN_LVL_MAX] */
  163. IMPORT int          year;                      /* Current year */
  164. IMPORT int          act_sec;                   /* Actual second */
  165. IMPORT int          act_min;                   /* Actual minute */
  166. IMPORT int          act_hour;                  /* Actual hour */
  167. IMPORT int          buf_ad;                    /* Buffer of actual day */
  168. IMPORT int          buf_am;                    /* Buffer of actual month */
  169. IMPORT int          buf_ay;                    /* Buffer of actual year */
  170. IMPORT char        *prgr_name;                 /* Stores the actual program name */
  171. IMPORT char         s[MAXLEN+1];               /* General purpose text buffer */
  172. IMPORT char         s2[MAXLEN+1];              /* General purpose text buffer */
  173.  
  174.  
  175.  
  176. /*
  177.    Define local(static) variables
  178. */
  179. #if USE_RC
  180. LOCAL char  str[MAXLEN+1];   /* General purpose text buffer */
  181. #endif
  182.  
  183.  
  184.  
  185. #ifdef ANSI_PROTO
  186. PUBLIC FILE *
  187. file_open (      char       *filename,
  188.            const Fmode_enum  mode)
  189. #else /* !ANSI_PROTO */
  190.    PUBLIC FILE *
  191. file_open (filename, mode)
  192.          char       *filename;
  193.    const Fmode_enum  mode;
  194. #endif /* !ANSI_PROTO */
  195. /*
  196.    Tries to open a resource/response (mode `REsource', `REsponse' or `USr_include')
  197.      file in following order:
  198.        1) actual directory
  199.        2) $HOME
  200.        3) $PATH(DOS) resp., $DPATH(OS/2) resp., $GCALPATH(UN*X and others)
  201.        4) GCAL_USR_LIBDIR (environment variable first; if unset then default name)
  202.        5) GCAL_SYS_LIBDIR (environment variable first; if unset then default name)
  203.      if success, return a file pointer to this file and it's name,
  204.      otherwise return a NULL pointer.
  205.    If mode is set to `SYs_include', this function tries to open an
  206.      include file (#include <file> directive found) only in:
  207.        1) GCAL_USR_LIBDIR (environment variable first; if unset then default name)
  208.        2) GCAL_SYS_LIBDIR (environment variable first; if unset then default name)
  209.      and returns a file pointer to this file and it's name,
  210.      otherwise a NULL pointer.
  211.    If mode is set to `COmmon', this function tries to open a
  212.      common file in
  213.        1) $PATH
  214.      and returns a file pointer to this file and it's name,
  215.      otherwise return a NULL pointer. NO informational messages will
  216.      be emitted in this mode!!
  217. */
  218. {
  219.    auto FILE   *fp=(FILE *)NULL;
  220.    auto char   *ptr_env;
  221.    auto char   *ptr_char;
  222. #if USE_RC
  223.    auto Bool    is_first=(Bool)((mode==REsource) ? TRUE : FALSE);
  224. #else /* !USE_RC */
  225.    auto Bool    is_first=FALSE;
  226. #endif /* !USE_RC */
  227.  
  228.  
  229.    strncpy(s, filename, MAXLEN+1);
  230.    s[MAXLEN] = '\0';
  231. #if USE_RC
  232.    if (mode != SYs_include)
  233. #endif
  234.     {
  235.       if (mode != COmmon)
  236.        {
  237.          /*
  238.             Try to open file (in actual directory)
  239.          */
  240.          fp = get_file_ptr (fp, filename, mode, &is_first);
  241.          /*
  242.             Absolute or relative file name delivered:
  243.               return to caller immediately
  244.          */
  245.          if (strchr(filename, *DIR_SEP) != (char *)NULL)
  246.           {
  247. #if USE_RC
  248.             if (   (fp == (FILE *)NULL)
  249.                 && (warning_level >= WARN_LVL_MAX))
  250.               /*
  251.                  Error, absolute file name not found
  252.               */
  253.               my_error (118, filename, 0, filename, 0);
  254. #endif /* USE_RC */
  255.             return(fp);
  256.           }
  257.        }
  258. #if !defined(AMIGA) || defined(__GNUC__)
  259.       if (mode != COmmon)
  260.        {
  261.          /*
  262.             Simple file name delivered and file not found in actual directory:
  263.               search for file
  264.          */
  265.          if (fp == (FILE *)NULL)
  266.           {
  267.             /*
  268.                File not found in actual directory:
  269.                  search file in the directory, which is
  270.                  stored in the environment variable:  HOME
  271.             */
  272.             ptr_env = getenv(ENV_VAR_HOME);
  273.             if (ptr_env != (char *)NULL)
  274.               if (*ptr_env)
  275.                {
  276.                  make_absolute_filename (ptr_env, filename);
  277.                  fp = get_file_ptr (fp, s, mode, &is_first);
  278.                }
  279.           }
  280.        }
  281.       if (fp == (FILE *)NULL)
  282.        {
  283.          /*
  284.             File not found in HOME directory:
  285.               search file in the directory(s), which are stored
  286.               in the environment variable:  [[D]|[GCAL]]PATH
  287.          */
  288.          if (mode == COmmon)
  289.            ptr_env = getenv(ENV_VAR_PATH);
  290.          else
  291.            ptr_env = getenv(ENV_VAR_DPATH);
  292.          if (ptr_env != (char *)NULL)
  293.            if (*ptr_env)
  294.             {
  295.               register int    i;
  296.               auto     Bool   ok=FALSE;
  297.  
  298.  
  299.               strncpy(s2, ptr_env, MAXLEN+1);
  300.               s2[MAXLEN] = '\0';
  301.               while (   !ok
  302.                      && (fp == (FILE *)NULL))
  303.                {
  304. #  ifdef SUFFIX_SEP
  305.                  if ((ptr_char=strchr(s2, *SUFFIX_SEP)) != (char *)NULL)
  306.                    *ptr_char = '\0';
  307. #  endif
  308.                  ok = (Bool)((ptr_char=strchr(s2, *PATH_SEP)) == (char *)NULL);
  309.                  if (ok)
  310.                    i = (int)strlen(s2);
  311.                  else
  312.                    i = (int)strlen(s2) - strlen(ptr_char);
  313.                  strcpy(s, s2);
  314.                  s[i] = '\0';
  315.                  ptr_char = strrchr(s, *DIR_SEP);
  316.                  if (ptr_char != (char *)NULL)
  317.                    if (strlen(ptr_char) > 1)
  318.                      strcat(s, DIR_SEP);
  319.                  strcat(s, filename);
  320.                  if (*s)
  321.                    fp = get_file_ptr (fp, s, mode, &is_first);
  322.                  if (ok)
  323.                    break;
  324.                  ptr_char = s2 + i + 1;
  325.                  strcpy(s2, ptr_char);
  326.                  if (*s2 == '\0')
  327.                    ok = TRUE;
  328.                }
  329.             }
  330.        }
  331.     }
  332. #  if USE_RC
  333.    if (mode != COmmon)
  334.     {
  335.       if (fp == (FILE *)NULL)
  336.        {
  337.          /*
  338.             File not found in one of the directories, which are
  339.             stored in the environment variable [[D]|[GCAL]]PATH:
  340.               search file in user library directory --> $HOME/GCAL_USR_LIBDIR
  341.          */
  342.          ptr_env = getenv(ENV_VAR_HOME);
  343.          if (ptr_env != (char *)NULL)
  344.            if (*ptr_env)
  345.             {
  346.               ptr_char = getenv(ENV_VAR_USR_LIBDIR);
  347.               /*
  348.                  Search file in directory specified in GCAL_USR_LIBDIR
  349.                    environment variable first
  350.               */
  351.               if (ptr_char != (char *)NULL)
  352.                {
  353.                  if (*ptr_char)
  354.                   {
  355.                     make_absolute_filename (ptr_env, ptr_char);
  356.                     strcpy(s2, s);
  357.                     make_absolute_filename (s2, filename);
  358.                     fp = get_file_ptr (fp, s, mode, &is_first);
  359.                   }
  360.                }
  361.               /*
  362.                  If GCAL_USR_LIBDIR environment variable unset,
  363.                    search file in burned-in user library directory --> GCAL_USR_LIBDIR
  364.               */
  365.               if (fp == (FILE *)NULL)
  366.                {
  367.                  make_absolute_filename (ptr_env, GCAL_USR_LIBDIR);
  368.                  strcpy(s2, s);
  369.                  make_absolute_filename (s2, filename);
  370.                  fp = get_file_ptr (fp, s, mode, &is_first);
  371.               }
  372.             }
  373.        }
  374.       if (fp == (FILE *)NULL)
  375.        {
  376.          /*
  377.             File not found in user library directory $HOME/GCAL_USR_LIBDIR:
  378.               search file in system library directory --> GCAL_SYS_LIBDIR
  379.          */
  380.          ptr_env = getenv(ENV_VAR_SYS_LIBDIR);
  381.          /*
  382.             Search file in directory specified in GCAL_SYS_LIBDIR
  383.               environment variable first
  384.          */
  385.          if (ptr_env != (char *)NULL)
  386.           {
  387.             if (*ptr_env)
  388.              {
  389.                make_absolute_filename (ptr_env, filename);
  390.                fp = get_file_ptr (fp, s, mode, &is_first);
  391.              }
  392.           }
  393.        }
  394.     }
  395. #  endif /* USE_RC */
  396. #else /* AMIGA && !__GNUC__ */
  397. #  if USE_RC
  398.    if (mode != COmmon)
  399.     {
  400.       /*
  401.          This part is for compilers/systems which don't have a getenv()-function
  402.       */
  403.       if (fp == (FILE *)NULL)
  404.        {
  405.          /*
  406.             File not found in actual directory:
  407.               search file in burned-in user library directory --> GCAL_SYS_LIBDIR
  408.          */
  409.          make_absolute_filename (GCAL_USR_LIBDIR, filename);
  410.          fp = get_file_ptr (fp, s, mode, &is_first);
  411.        }
  412.     }
  413. #  endif /* USE_RC */
  414. #endif /* AMIGA && !__GNUC__ */
  415. #if USE_RC
  416.    if (mode != COmmon)
  417.     {
  418.       if (fp == (FILE *)NULL)
  419.        {
  420.          /*
  421.             File not found in user library directory GCAL_USR_LIBDIR:
  422.               search file in burned-in system library directory --> GCAL_SYS_LIBDIR
  423.          */
  424.          make_absolute_filename (GCAL_SYS_LIBDIR, filename);
  425.          fp = get_file_ptr (fp, s, mode, &is_first);
  426.        }
  427.     }
  428. #endif /* USE_RC */
  429.    /*
  430.       If file found:
  431.         copy real (absolute) name of file to `filename'
  432.    */
  433.    if (fp != (FILE *)NULL)
  434.      strcpy(filename, s);
  435. #if USE_RC
  436.    else
  437.      if (   (warning_level >= WARN_LVL_MAX)
  438.          && (mode != COmmon))
  439.        /*
  440.           Terminate if --debug=abort option is given
  441.        */
  442.        my_error (118, filename, 0, filename, 0);
  443. #endif
  444.  
  445.    return(fp);
  446. }
  447.  
  448.  
  449.  
  450. #ifdef ANSI_PROTO
  451. PUBLIC char *
  452. file_read_line (      FILE       *fp,
  453.                       char       *line_buffer,
  454.                       int        *in_pool,
  455.                       char       *pool,
  456.                       char       *ptr_pool,
  457.                 const char       *filename,
  458.                       int        *line,
  459.                 const Fmode_enum  mode,
  460.                       Bool       *is_include,
  461.                       Bool       *is_dvar)
  462. #else /* !ANSI_PROTO */
  463.    PUBLIC char *
  464. file_read_line (fp, line_buffer, in_pool, pool, ptr_pool, filename, line, mode, is_include, is_dvar)
  465.          FILE       *fp;
  466.          char       *line_buffer;
  467.          int        *in_pool;
  468.          char       *pool;
  469.          char       *ptr_pool;
  470.    const char       *filename;
  471.          int        *line;
  472.    const Fmode_enum  mode;
  473.          Bool       *is_include;
  474.          Bool       *is_dvar;
  475. #endif /* !ANSI_PROTO */
  476. /*
  477.    Reads a line of delivered resource/response file into `line_buffer'
  478.      using delivered char vector `pool', which must be allocated by caller
  479.      with size BUF_LEN+1 (BUF_LEN should be a power of 2, e.g., 4096).
  480.      returns the position in buffer of last managed character by char pointer
  481.      `ptr_pool', which must be defined by caller; or NULL if EOF is detected.
  482. */
  483. {
  484.    register int    i;
  485.    auto     char  *ptr_char=line_buffer;
  486.    auto     char   ch;
  487.    auto     Bool   is_error=FALSE;
  488.  
  489.  
  490.  
  491.    *is_include=*is_dvar = FALSE;
  492.    /*
  493.       Initial fill/refill `pool'
  494.    */
  495.    if (!*in_pool)
  496.     {
  497.       *in_pool = read(fileno(fp), (char *)pool, BUF_LEN);
  498.       if (!*in_pool)
  499.         /*
  500.            At end of file
  501.         */
  502.         return((char *)NULL);
  503.       else
  504.         if (*in_pool < 0)
  505.           /*
  506.              File read error
  507.           */
  508.           my_error (109, filename, 0, "", 0);
  509.       ptr_pool = pool;
  510.     }
  511.    if (*ptr_pool == '\n')
  512.      (*line)++;
  513.    while (   (*ptr_pool != REM_CHAR)
  514.           && (
  515. #if USE_RC
  516.                  (   (mode == REsource)
  517.                   && (*ptr_pool != *RC_INCL_STMENT)
  518.                   && (*ptr_pool != RC_HDY_CHAR)
  519.                   && (*ptr_pool != RC_NWD_CHAR)
  520.                   && !isalnum(*ptr_pool))
  521.               ||
  522. #endif
  523.                  (   (mode == REsponse)
  524.                   && (*ptr_pool != *MONTH3_LIT)
  525.                   && (*ptr_pool != *FYEAR_SEP)
  526.                   && (*ptr_pool != RSP_CHAR)
  527.                   && !isalnum(*ptr_pool)
  528. #if USE_RC
  529.                   && (*ptr_pool != RC_ADATE_CHAR)
  530. #endif
  531.                   && (*ptr_pool != *SWITCH)
  532.                   && (*ptr_pool != *SWITCH2))))
  533.     {
  534.       ptr_pool++;
  535.       (*in_pool)--;
  536.       if (!*in_pool)
  537.        {
  538.          /*
  539.             Refill `pool', because the line we work on isn't complete
  540.          */
  541.          *in_pool = read(fileno(fp), (char *)pool, BUF_LEN);
  542.          if (!*in_pool)
  543.            /*
  544.               At end of file
  545.            */
  546.            return((char *)NULL);
  547.          else
  548.            if (*in_pool < 0)
  549.              /*
  550.                 File read error
  551.              */
  552.              my_error (109, filename, 0, "", 0);
  553.          ptr_pool = pool;
  554.        }
  555.       if (*ptr_pool == '\n')
  556.         (*line)++;
  557.     }
  558.    (*line)++;
  559.    /*
  560.       Skip whole line
  561.    */
  562.    if (*ptr_pool == REM_CHAR)
  563.     {
  564.       /*
  565.          Read until NEWLINE or EOF
  566.       */
  567.       while (*ptr_pool != '\n')
  568.        {
  569.          /*
  570.             Refill `pool', because the line we work on isn't complete
  571.          */
  572.          if (!*in_pool)
  573.           {
  574.             *in_pool = read(fileno(fp), (char *)pool, BUF_LEN);
  575.             if (!*in_pool)
  576.               /*
  577.                  At end of file
  578.               */
  579.               return((char *)NULL);
  580.             else
  581.               if (*in_pool < 0)
  582.                 /*
  583.                    File read error
  584.                 */
  585.                 my_error (109, filename, 0, "", 0);
  586.             ptr_pool = pool;
  587.           }
  588.          else
  589.           {
  590.             ptr_pool++;
  591.             (*in_pool)--;
  592.           }
  593.        }
  594.       /*
  595.          Skip NEWLINE character
  596.       */
  597.       ptr_pool++;
  598.       if (*in_pool)
  599.         (*in_pool)--;
  600.     }
  601.    else
  602.     {
  603. #if USE_RC
  604.       if (mode == REsource)
  605.        {
  606.          if (*ptr_pool == *RC_INCL_STMENT)
  607.            *is_include = TRUE;
  608.          else
  609.            if (   isupper(*ptr_pool)
  610.                || islower(*ptr_pool))
  611.              *is_dvar = TRUE;
  612.            else
  613.              if (!isdigit(*ptr_pool))
  614.                is_error = TRUE;
  615.        }
  616. #endif
  617.       ch=(*ptr_char++) = *ptr_pool++;
  618.       (*in_pool)--;
  619.       i = 1;
  620.       LOOP
  621.        {
  622.          if (*in_pool)
  623.           {
  624.             i++;
  625.             /*
  626.                Character sequence `\\'`\n' (BACKSLASH-NEWLINE) found:
  627.                  quote newline char and append next line to current line
  628.             */
  629.             if (   (*ptr_pool == '\n')
  630.                 && (ch == QUOTE_CHAR))
  631.              {
  632.                if (is_error)
  633.                 {
  634.                   (*in_pool)--;
  635.                   break;
  636.                 }
  637.                (*line)++;
  638.                if (i < MAXLEN)
  639.                 {
  640.                   ptr_char--;
  641.                   i -= 2;
  642.                   if (*in_pool)
  643.                     ptr_pool++;
  644.                 }
  645.              }
  646.             else
  647.               /*
  648.                  Single NEWLINE character found:
  649.                    finish line
  650.               */
  651.               if (*ptr_pool == '\n')
  652.                {
  653.                  ptr_pool++;
  654.                  (*in_pool)--;
  655.                  break;
  656.                }
  657.               else
  658.                 if (i < MAXLEN)
  659.                   ch=(*ptr_char++) = *ptr_pool++;
  660.             (*in_pool)--;
  661.           }
  662.          /*
  663.             Refill `pool', because the line we work on isn't complete
  664.          */
  665.          if (!*in_pool)
  666.           {
  667.             *in_pool = read(fileno(fp), (char *)pool, BUF_LEN);
  668.             if (!*in_pool)
  669.               /*
  670.                  At end of file
  671.               */
  672.               return((char *)NULL);
  673.             else
  674.               if (*in_pool < 0)
  675.                 /*
  676.                    File read error
  677.                 */
  678.                 my_error (109, filename, 0, "", 0);
  679.             ptr_pool = pool;
  680.           }
  681.        }
  682.     }
  683.    *ptr_char = '\0';
  684. #if USE_RC
  685.    /*
  686.       Check for local date variable definition
  687.    */
  688.    if (*is_dvar)
  689.      if (!set_dvar (line_buffer, filename, *line, LOcal))
  690.        /*
  691.           Error, unable to store date variable
  692.        */
  693.        my_error (114, filename, *line, line_buffer, 0);
  694.    if (   is_error
  695.        && (mode == REsource))
  696.      /*
  697.         Error, invalid date field given
  698.      */
  699.      my_error (123, filename, *line, line_buffer, 0);
  700. #endif
  701.  
  702.    return(ptr_pool);
  703. }
  704.  
  705.  
  706.  
  707. #ifdef ANSI_PROTO
  708. PUBLIC void
  709. insert_response_file (      char *filename,
  710.                       const char *opt_list,
  711.                             int  *my_argc_max,
  712.                             int  *my_argc,
  713.                             char *my_argv[])
  714. #else /* !ANSI_PROTO */
  715.    PUBLIC void
  716. insert_response_file (filename, opt_list, my_argc, my_argv)
  717.          char *filename;
  718.    const char *opt_list;
  719.          int  *my_argc_max;
  720.          int  *my_argc;
  721.          int  *my_argv[];
  722. #endif /* !ANSI_PROTO */
  723. /*
  724.    Tries to manage a response file "@file" argument given in command line,
  725.      the '@' character must be the first character of file name.  inserts the
  726.      options and commands found in file "@file" (name delivered in `filename')
  727.      into `*my_argc[]' and sets delivered `*my_argc' and perhaps `*my_argc_max'
  728.      to according "new" values.  uses global variable `s' internally.
  729. */
  730. {
  731.    auto FILE  *fp=(FILE *)NULL;
  732.  
  733.  
  734.    fp = file_open (filename, REsponse);
  735.    if (fp != (FILE *)NULL)
  736.     {
  737.       auto int    line=0;
  738.       auto int    in_pool=0;
  739.       auto char  *pool=(char *)NULL;
  740.       auto char  *ptr_pool=(char *)NULL;
  741.       auto Bool   b_dummy;   /* Dummy */
  742.  
  743.  
  744.       pool = (char *)my_malloc (BUF_LEN+1, 124, __FILE__, __LINE__, "pool", 0);
  745.       while ((ptr_pool=file_read_line (fp, s, &in_pool, pool, ptr_pool,
  746.                                        filename, &line, REsponse, &b_dummy, &b_dummy)) != (char *)NULL)
  747.         if (*s)
  748.          {
  749.            register int  len=0;
  750.  
  751.  
  752.            /*
  753.               Leading whitespace characters eliminated by file_read_line(),
  754.                 so truncate line at first whitespace character found.
  755.            */
  756.            while (   s[len]
  757.                   && !MY_ISSPACE(s[len]))
  758.              len++;
  759.            if (   (   *s == *SWITCH
  760.                    || *s == *SWITCH2)
  761.                && s[1]
  762.                && (s[1] != *SWITCH))
  763.              /*
  764.                 Short-style option found
  765.              */
  766.              if (strchr(opt_list, s[1]) != (char *)NULL)
  767.               {
  768.                 register int  spaces=0;
  769.                 register int  newpos=0;
  770.  
  771.  
  772.                 /*
  773.                    Short-style option requires an argument, which could be separated
  774.                      by whitespace characters from the option character; respect this!
  775.                      this means all separating whitespace characters between the
  776.                      option character and argument will be eliminated.
  777.                 */
  778.                 while (   s[len+spaces]
  779.                        && MY_ISSPACE(s[len+spaces]))
  780.                   spaces++;   /* Count the separating whitespace characters. */
  781.                 /*
  782.                    Store needed argument of option adjacent to option character.
  783.                 */
  784.                 while (   s[len+spaces]
  785.                        && !MY_ISSPACE(s[len+spaces]))
  786.                  {
  787.                    s[len+newpos++] = s[len+spaces];
  788.                    len++;
  789.                  }
  790.              }
  791.            s[len] = '\0';
  792.            /*
  793.               Avoid one or two letter combinitions of '-', '/' or '%' characters only!
  794.            */
  795.            if (       (   (len == 1)
  796.                    && (   *s == *SWITCH
  797. #if USE_RC
  798.                        || *s == RC_ADATE_CHAR
  799. #endif
  800.                        || *s == *SWITCH2))
  801.                || (   (len == 2)
  802.                    && (   *s == *SWITCH
  803. #if USE_RC
  804.                        || *s == RC_ADATE_CHAR
  805. #endif
  806.                        || *s == *SWITCH2)
  807.                    && (   s[1] == *SWITCH
  808. #if USE_RC
  809.                        || s[1] == RC_ADATE_CHAR
  810. #endif
  811.                        || s[1] == *SWITCH2)))
  812.              ;   /* Void, don't allocate memory */
  813.            else
  814.             {
  815.               if (*my_argc >= *my_argc_max)
  816.                {
  817. #if HAVE_ASSERT_H
  818.                  /*
  819.                     Check if value for maximum number of table entries
  820.                       fits to the positive range of a signed int(INT_MAX)!!
  821.                  */
  822.                  assert((Uint)*my_argc_max+MY_ARGC_MAX<=testval);
  823. #endif
  824.                  /*
  825.                     Resize the table
  826.                  */
  827.                  *my_argc_max += MY_ARGC_MAX;
  828.                  my_argv = (char **)my_realloc (my_argv, *my_argc_max*sizeof(char *),
  829.                                                 124, __FILE__, __LINE__ -1,
  830.                                                 "my_argc", *my_argc_max);
  831.                }
  832.               my_argv[*my_argc] = (char *)my_malloc (len+1,
  833.                                                      124, __FILE__, __LINE__ -1,
  834.                                                      "my_argc", *my_argc);
  835.               strcpy(my_argv[(*my_argc)++], s);
  836.             }
  837.          }
  838.       fclose(fp);
  839.       free(pool);
  840.     }
  841. }
  842.  
  843.  
  844.  
  845. #ifdef ANSI_PROTO
  846. PUBLIC void
  847. write_log_file (const char       *filename,
  848.                 const Fmode_enum  mode,
  849.                 const char       *mode_msg,
  850.                 const int         argc,
  851.                       char       *argv[])
  852. #else /* !ANSI_PROTO */
  853.    PUBLIC void
  854. write_log_file (filename, mode, mode_msg, argc, argv)
  855.    const char       *filename;
  856.    const Fmode_enum  mode;
  857.    const char       *mode_msg;
  858.    const int         argc;
  859.          char       *argv[];
  860. #endif /* !ANSI_PROTO */
  861. /*
  862.    Writes the contents of the environment variable GCAL, which is already
  863.      stored in `argc' and the arguments of command line either into a
  864.      response file (mode==REsponse) or into a shell script (mode==SCript);
  865.      other settings to `mode' will `abort()' the program immediately.
  866. */
  867. {
  868.    auto     FILE  *fp=(FILE *)NULL;
  869.    auto     int    len=0;
  870.    register int    i=0;
  871.  
  872.  
  873.    fp = fopen(filename, "w");
  874.    if (fp != (FILE *)NULL)
  875.     {
  876.       switch (mode)
  877.        {
  878.          case REsponse:
  879.            len = fprintf(fp, "%c `%s' %s `%s' -- "
  880.                          "%04d/%02d/%02d %02d"TIME_SEP"%02d"TIME_SEP"%02d\n%c\n",
  881.                          REM_CHAR, prgr_name, mode_msg, filename,
  882.                          buf_ay, buf_am, buf_ad, act_hour, act_min, act_sec,
  883.                          REM_CHAR);
  884.            break;
  885. #  ifdef GCAL_SHELL
  886.          case SCript:
  887. #    if HAVE_SYS_INTERPRETER
  888.            len = fprintf(fp, "%s\n%c\n%c `%s' %s `%s' -- "
  889.                          "%04d/%02d/%02d %02d"TIME_SEP"%02d"TIME_SEP"%02d\n%c\n%s",
  890.                          SHELL, *SHL_REM, *SHL_REM, prgr_name, mode_msg, filename,
  891.                          buf_ay, buf_am, buf_ad, act_hour, act_min, act_sec,
  892.                          *SHL_REM, prgr_name);
  893. #    else /* !HAVE_SYS_INTERPRETER */
  894.            len = fprintf(fp, "%c `%s' %s `%s' -- "
  895.                          "%04d/%02d/%02d %02d"TIME_SEP"%02d"TIME_SEP"%02d\n%c\n%s",
  896.                          *SHL_REM, prgr_name, mode_msg, filename,
  897.                          buf_ay, buf_am, buf_ad, act_hour, act_min, act_sec,
  898.                          *SHL_REM, prgr_name);
  899. #    endif /* !HAVE_SYS_INTERPRETER */
  900.            break;
  901. #endif /* GCAL_SHELL */
  902.          default:
  903.            /*
  904.               This case MUST be an internal error!
  905.            */
  906.            abort();
  907.        }
  908.       if (len != EOF)
  909.        {
  910.          for (i=1 ; i < argc ; i++)
  911.           {
  912.             /*
  913.                Don't write the name of a response file or of a
  914.                 shell script into the response file!
  915.             */
  916.             if (   *argv[i] == *SWITCH
  917.                 || *argv[i] == *SWITCH2)
  918.              {
  919.                /*
  920.                   If short option -R<NAME> or -S<NAME> is given, skip!
  921.                */
  922.                if (   *(argv[i]+1) == 'R'
  923. #ifdef GCAL_SHELL
  924.                    || *(argv[i]+1) == 'S'
  925. #endif
  926.                   )
  927.                  continue;
  928.                if (*(argv[i]+1) == *SWITCH)
  929.                 {
  930.                   /*
  931.                      Detect whether long option --response-file=ARG
  932.                        or --shell-script=ARG is given and if found,
  933.                        don't write this option in the response file!
  934.                   */
  935.                   strcpy(str, argv[i]+2);
  936.                   (void)eval_longopt (str, &len);
  937.                   if (len == SYM_RESPONSE_FILE)
  938.                     continue;
  939. #ifdef GCAL_SHELL
  940.                   if (len == SYM_SCRIPT_FILE)
  941.                     continue;
  942. #endif
  943.                 }
  944.              }
  945.             switch (mode)
  946.              {
  947.                case REsponse:
  948.                  len = fprintf(fp, "%s\n", argv[i]);
  949.                  break;
  950. #ifdef GCAL_SHELL
  951.                case SCript:
  952.                  len = fprintf(fp, " \"%s\"", argv[i]);
  953.                  break;
  954. #endif
  955.                default:
  956.                  /*
  957.                     This case can't occur anymore, if so,
  958.                       it MUST be an internal error!
  959.                  */
  960.                  abort();
  961.              }
  962.             if (len == EOF)
  963.               break;
  964.           }
  965. #ifdef GCAL_SHELL
  966.          if (mode == SCript)
  967.            len = fprintf(fp, " $*\n");
  968. #endif
  969.          i = fclose(fp);
  970.        }
  971.     }
  972.    else
  973.      len = EOF;
  974.    if (i == EOF)
  975.      len = EOF;
  976.    if (   (   (len != EOF)
  977.            && (warning_level == 1))
  978.        || (   (len == EOF)
  979.            && (warning_level == 2))
  980.        || warning_level > 2)
  981.     {
  982. #if USE_GER
  983.       sprintf(str, "Versuche %s `%s' zu schreiben... %s%s%s", mode_msg, filename,
  984.               (ehls1s.len!=1) ? ((len==EOF) ? ehls2s.seq : ehls1s.seq) : "",
  985.               (len==EOF) ? "Versagt" : "Erfolg",
  986.               (ehls1s.len!=1) ? ((len==EOF) ? ehls2e.seq : ehls1e.seq) : "");
  987. #else /* !USE_GER */
  988.       sprintf(str, "Try to write %s `%s'... %s%s%s", mode_msg, filename,
  989.               (ehls1s.len!=1) ? ((len==EOF) ? ehls2s.seq : ehls1s.seq) : "",
  990.               (len==EOF) ? "failed" : "success",
  991.               (ehls1s.len!=1) ? ((len==EOF) ? ehls2e.seq : ehls1e.seq) : "");
  992. #endif /* !USE_GER */
  993.       print_text (stderr, str, INternal);
  994.       /*
  995.          Terminate program in case the file can't be written
  996.       */
  997.       if (   (len == EOF)
  998.           && (warning_level >= WARN_LVL_MAX))
  999.         my_error (115, filename, 0, filename, 0);
  1000.     }
  1001. #ifdef GCAL_SHELL
  1002.    if (   (mode == SCript)
  1003.        && (len != EOF))
  1004.     {
  1005.       /*
  1006.          Try to make the created shell script executable
  1007.       */
  1008.       sprintf(str, CHMOD_PRGR" "CHMOD_OPTS" %s", filename);
  1009.       /*
  1010.          And ignore any errors...
  1011.       */
  1012.       (void)system(str);
  1013.     }
  1014. #endif /* GCAL_SHELL */
  1015. }
  1016.  
  1017.  
  1018.  
  1019. #ifdef ANSI_PROTO
  1020. LOCAL FILE *
  1021. get_file_ptr (      FILE       *fp,
  1022.               const char       *filename,
  1023.               const Fmode_enum  mode,
  1024.                     Bool       *is_first)
  1025. #else /* !ANSI_PROTO */
  1026.    LOCAL FILE *
  1027. get_file_ptr (fp, filename, mode, is_first)
  1028.          FILE       *fp;
  1029.    const char       *filename;
  1030.    const Fmode_enum  mode;
  1031.          Bool       *is_first;
  1032. #endif /* !ANSI_PROTO */
  1033. /*
  1034.    Tries to open the file (with optional diagnostic messages
  1035.      --debug[=0...WARN_LVL_MAX]) and returns a pointer to that file
  1036.      or NULL if fails
  1037. */
  1038. {
  1039.    fp = fopen(filename, "r");
  1040.    if (   (warning_level >= 0)
  1041.        && (mode != REsponse)
  1042.        && (mode != COmmon))
  1043. #if USE_RC
  1044.     {
  1045.       if (   (   (fp != (FILE *)NULL)
  1046.               && (warning_level == 1))
  1047.           || (   (fp == (FILE *)NULL)
  1048.               && (warning_level == 2))
  1049.           || warning_level > 2)
  1050.        {
  1051.          /*
  1052.             If this function is entered the first time:
  1053.               print a leading newline before any warning texts
  1054.          */
  1055.          if (*is_first)
  1056.           {
  1057.             *is_first = FALSE;
  1058.             *str = '\0';
  1059.             print_text (stderr, str, INternal);
  1060.           }
  1061. #  if USE_GER
  1062.          sprintf(str, "Versuche %s-Datei `%s' zu "OE"ffnen... %s%s%s",
  1063.                  (mode==REsource) ? "Resourcen" : "Include", filename,
  1064.                  (ehls1s.len!=1) ? ((fp==(FILE *)NULL) ? ehls2s.seq : ehls1s.seq) : "",
  1065.                  (fp==(FILE *)NULL) ? "Versagt" : "Erfolg",
  1066.                  (ehls1s.len!=1) ? ((fp==(FILE *)NULL) ? ehls2e.seq : ehls1e.seq) : "");
  1067. #  else /* !USE_GER */
  1068.          sprintf(str, "Try to open %s file `%s'... %s%s%s",
  1069.                  (mode==REsource) ? "resource" : "include", filename,
  1070.                  (ehls1s.len!=1) ? ((fp==(FILE *)NULL) ? ehls2s.seq : ehls1s.seq) : "",
  1071.                  (fp==(FILE *)NULL) ? "failed" : "success",
  1072.                  (ehls1s.len!=1) ? ((fp==(FILE *)NULL) ? ehls2e.seq : ehls1e.seq) : "");
  1073. #  endif /* !USE_GER */
  1074.          print_text (stderr, str, INternal);
  1075.        }
  1076.     }
  1077. #else /* !USE_RC */
  1078.      ;   /* Void */
  1079. #endif /* !USE_RC */
  1080.  
  1081.    return(fp);
  1082. }
  1083.  
  1084.  
  1085.  
  1086. #ifdef ANSI_PROTO
  1087. LOCAL void
  1088. make_absolute_filename (const char *directory,
  1089.                         const char *filename)
  1090. #else /* !ANSI_PROTO */
  1091.    LOCAL void
  1092. make_absolute_filename (directory, filename)
  1093.    const char *directory;
  1094.    const char *filename;
  1095. #endif /* !ANSI_PROTO */
  1096. /*
  1097.    Creates an absolute file name (directory+file name) of a delivered
  1098.      file name and directory and returns the result to the concatenated
  1099.      absolute file name in the global variable `s'
  1100. */
  1101. {
  1102.    register int  len=(int)strlen(DIR_SEP)+strlen(filename);
  1103.    register int  len2;
  1104.  
  1105.  
  1106.    strncpy(s, directory, MAXLEN+1);
  1107.    s[MAXLEN] = '\0';
  1108.    len2 = (int)strlen(s);
  1109.    if (len + len2 > MAXLEN)
  1110.     {
  1111.       if (len < MAXLEN)
  1112.       strcpy(s, filename);
  1113.     }
  1114.    else
  1115.     {
  1116.       if (s[len2-1] != *DIR_SEP)
  1117.         strcat(s, DIR_SEP);
  1118.       strcat(s, filename);
  1119.     }
  1120. }
  1121.